import { IEventTarget } from "./interfaces";

/// reference: https://developer.mozilla.org/zh-CN/docs/Web/API/Event
export class Event {
    /**
  * The type of event, supports the following:
  * * pointerdown
  * * touchstart
  * * mousedown
  * * rightdown
  * * ...
  */
    type: string;

    /**
     * A boolean value indicating whether the event bubbles. The default is false.
  * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/bubbles
  *
  */
    bubbles: boolean;

    /**
     * A boolean value indicating whether the event can be cancelled. The default is false.
  * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/cancelBubble
  */
    cancelable: boolean;

    // A boolean value indicating whether the event will trigger listeners outside of a shadow root (see Event.composed for more details).
    composed: boolean;

    /** the event target when listeners binded */
    currentTarget: IEventTarget | null;

    /**
    * can be used to implement event delegation
    * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/target
    */
    target: IEventTarget | null;

    /**
  * timestamp when the event created
  * DateTime.now().millisecondsSinceEpoch
  * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/timeStamp
  */
    timeStamp: number;

    /** Flags whether the default response of the user agent was prevent through this event. */
    defaultPrevented = false;

    /** Flags whether propagation was immediately stopped. */
    propagationImmediatelyStopped = true;

    /** Flags whether propagation was stopped. */
    propagationStopped = false;

    /**
     * The event boundary which manages this event. Propagation can only occur
     *  within the boundary's jurisdiction.
     */
    constructor(type: string, options?: { bubbles?: boolean; cancelable?: boolean; composed?: boolean }) {
        this.type = type;

        this.bubbles = options?.bubbles ?? false;
        this.cancelable = options?.cancelable ?? false;
        this.composed = options?.composed ?? false;
    }

    path: IEventTarget[];
    /**
     * The propagation path for this event
     * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/composedPath
     *
     * So composedPath()[0] represents the original target.
     * @see https://polymer-library.polymer-project.org/3.0/docs/devguide/events#retargeting
     */
    composedPath(): IEventTarget[] {
        if (!this.path || this.path[0] !== this.target) {
            this.path = this.target ? [this.target] : [];
        }

        return this.path;
    }

    /**
   * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/preventDefault
   */
    preventDefault(): void {
        // antvis/g
        // if (this.nativeEvent instanceof Event && this.nativeEvent.cancelable) {
        //     this.nativeEvent.preventDefault();
        // }

        // this.defaultPrevented = true;

        // webf
        if (this.cancelable) {
            this.defaultPrevented = true;
        }
    }

    /**
  * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation
  */
    stopImmediatePropagation(): void {
        this.propagationImmediatelyStopped = true;
    }

    /**
   * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopPropagation
   */
    stopPropagation(): void {
        // antvis/g
        //this.propagationStopped = true;

        // webf
        this.bubbles = false;
    }

    isTrusted: boolean;

    /**
      * added for compatibility with DOM Event,
      * @deprecated props and methods
      */
    initEvent(): void { }

    /**
     *  @deprecated
     */
    srcElement: IEventTarget;


    /**
     *  @deprecated
     */
    returnValue: boolean;


    /**
     *  @deprecated
    */
    //get propagationPath() {
    //    return this.composedPath();
    //}

    // canBubble(): boolean {
    //     return this.propagationImmediatelyStopped
    // };

    // initUIEvent(): void { }
    // clone() {
    //     throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
    // }

    /**
    * @see https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/view
    */
    //view: any;
    //which: number;
    //NONE = 0;
    //CAPTURING_PHASE = 1;
    //AT_TARGET = 2;
    //BUBBLING_PHASE = 3;
}
